package base;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;

import util.PairList;

import base.Global.NetType;

/**
 * @name InterfaceNetwork
 * @description 网络的基本功能
 * @author Mervin.Wong
 * @version 0.1.0
 */
public interface InterfaceNetOperation {
	
	/**
	 * @name getCurrentNodeNum 
	 * @description 获取当前节点的数量
	 * @return int currentNodeNum
	 */
	//public int getCurrentNodeNum();
	
	/**
	 * @name getCurrentEdgeNum 
	 * @description 获取当前节点的数量
	 * @return int currentEdgeNum
	 */
	//public int getCurrentEdgeNum();
	
	/**
	 * @name getNodeByIndex
	 * @description 获取拓扑上的一个节点\
	 * @param int index 节点数组的索引号  ArrayList<Map<String, Object>> topology 
	 * @return Node node 
	 */
	//public Node getNodeByIndex(int index);
	/**
	 * @name getFirstNode
	 * @description 获取网络中的第一个节点
	 */
	public Node getFirstNode();
	
	/**
	 * @name getFirstNodeId
	 * @description 获取网络中的第一个节点的ID
	 * @return
	 */
	public Number getFirstNodeId();
	
	/**
	 * @name getLastNode
	 * @description 获取最后一个节点
	 * @return
	 */
	public Node getLastNode();
	/**
	 * @name getLastNodeId
	 * @description 获取最后一个节点的ID
	 * @return
	 */
	public Number getLastNodeId();
	/**
	 * @name getNodeById
	 * @description 获取拓扑上的一个节点
	 * @param Number nodeId 节点id
	 * @return Map node 
	 */
	public Node getNodeById(Number nodeId);
	
	/**
	 * @name getNodeIndex
	 * @description 获取节点在拓扑网络数组中的索引号
	 * @param Map node
	 * @return int nodeIndex
	 */
	//public int getNodeIndex(Map<String, Object> node);
		
	/**
	 * @name getNodeIndex
	 * @description 获取节点在拓扑网络数组中的索引号
	 * @param Number nodeId
	 * @return int nodeIndex
	 */
	//public int getNodeIndex(Number nodeId);
	
	/**
	 * @name getNodeId
	 * @description 获取节点的ID
	 * @param Map node
	 * @return Number nodeId
	 */
	public Number getNodeId(Node node);
	
	/**
	 * @name getNodeId
	 * @description 获取节点的ID
	 * @param int nodeIndex
	 * @return Number nodeId
	 */
	//public Number getNodeId(int nodeIndex);
	
	/**
	 * @name getNodeWeigh
	 * @description 获取节点的权重
	 * @param Map node
	 * @return Integer nodeWeigh
	 */
	public int getNodeWeigh(Node node);

	/**
	 * @name getNodeWeigh
	 * @description 获取节点的权重
	 * @param Number nodeId
	 * @return Integer nodeWeigh
	 */
	public int getNodeWeigh(Number nodeId);
	
	/**
	 * @name getEdgeWeight
	 * @decription 获取边的权重
	 * @param preNode
	 * @param postNode
	 * @return int
	 */
	public int getEdgeWeight(Node preNode, Node postNode);
	
	/**
	 * @name getEdgeWeight
	 * @description 获取边的权重
	 * @param preNodeId
	 * @param postNodeId
	 * @return int
	 */
	public int getEdgeWeight(Number preNodeId, Number postNodeId);
	/**
	 * @getNodeIndexByNodeId
	 * @description 通过节点的ID获取该节点在拓扑数组中的索引
	 * @param Number nodeId
	 * @return int nodeIndex 
	 */
	//public int getNodeIndexByNodeId(Number nodeId);
	
	/**
	 * @name getNodeIdByNodeIndex
	 * @description 通过拓扑数组中的索引获取该节点的ID
	 * @param int nodeIndex
	 * @return Number nodeId
	 */
	//public Number getNodeIdByNodeIndex(int nodeIndex);
	
	/**
	 * @name getNodeFirstAdjNodes
	 * @description 获取该节点的邻接点
	 * @param Map node
	 * @return LinkedList firstAdjNode
	 */
	public LinkedList<Edge> getAdjNodes(Node node);
	
	/**
	 * @name getNodeFirstAdjNode
	 * @description 获取该节点的第一个邻接点
	 * @param Number nodeId
	 * @return LinkedList firstAdjNode
	 */
	public LinkedList<Edge> getAdjNodes(Number nodeId);
	
	/**
	 * @name getNodeAdjNode
	 * @description 获取节点的邻接点,注：在数据结构上
	 * @param Number nodeId
	 * @return Number[] adjNodeId
	 */
	public HashSet<Number> getAdjNodesId(Number nodeId);
	
	/**
	 * @name getInDegreeNodes
	 * @description 查找某节点的入度节点，注在有向网络中
	 * @param Number nodeId
	 * @return int[] inDegreeNode
	 */
	public HashSet<Number> getInDegreeNodesId(Number nodeId);
	/**
	 * @name getOutDegreeNodes
	 * @description 查找节点的出度节点，注在有向网络中
	 * @param Number nodeId
	 * @return int[] outDegreeNode
	 */
	public HashSet<Number> getOutDegreeNodesId(Number nodeId);
	
	/**
	 * @name getPreNode
	 * @description 获取节点nodeId的前一个节点
	 * @param nodeId
	 * @return
	 */
	public Node getPreNode(Number nodeId);
	/**
	 * @name getPostNode
	 * @description 获取节点nodeId的后一个节点
	 * @param nodeId
	 * @return
	 */
	public Node getPostNode(Number nodeId);
	
	/**
	 * @name getRandNode
	 * @description 获取一个随机节点
	 * @return
	 */
	public Node getRandNode();
	/**
	 * @name getRandNodeId
	 * @description 获取一个随机节点ID
	 * @return
	 */
	public Number getRandNodeId();
	/**
	 * @name updateNodeWeigh
	 * @description 更新节点的权值
	 * @param node
	 * @param nodeWeigh
	 * @return
	 */
	public void updateNodeWeigh(Node node, int nodeWeigh);
	/**
	 * @name updateNodeWeigh
	 * @description 更新节点的权值
	 * @param nodeId
	 * @param nodeWeigh
	 * @return
	 */
	public void updateNodeWeigh(Number nodeId, int nodeWeigh);
	
	/**
	 * @name updateEdgeWeigh
	 * @description 更新变得权值
	 * @param preNode
	 * @param postNode
	 * @param edgeWeigh
	 * @return
	 */
	public boolean updateEdgeWeigh(Node preNode, Node postNode, int edgeWeigh);
	
	/**
	 * @name updateEdgeWeigh
	 * @description 更新变得权值
	 * @param preNodeId
	 * @param postNodeId
	 * @param edgeWeigh
	 * @return
	 */
	public boolean updateEdgeWeigh(Number preNodeId, Number postNodeId, int edgeWeigh);
	
	/**
	 * @name isHasNode
	 * @description 判断节点nodeId是否存在
	 * @param nodeId
	 * @return
	 */
	public boolean isHasNode(Number nodeId);
	/**
	 * @name isHasEdge
	 * @description 判断两个节点之间是否相连
	 * @param preNode
	 * @param postNode
	 * @return boolean
	 */
	public boolean isHasEdge(Node preNode, Node postNode);
	/**
	 * @name isHasEdge
	 * @param Number preNodeId
	 * @param Number postNodeId
	 * @return boolean
	 */
	public boolean isHasEdge(Number preNodeId, Number postNodeId);

	/**
	 * @name isHasLink
	 * @description 判断两点之间是否存在链路
	 * @param preNode
	 * @param postNode
	 * @return
	 */
	public boolean isHasLink(Node preNode, Node postNode);
	
	/**
	 * @name isHasLink
	 * @description 判断两点之间是否存在链路
	 * @param preNodeId
	 * @param postNodeId
	 * @return
	 */
	public boolean isHasLink(Number preNodeId, Number postNodeId);
	
	/**
	 * @name isConnectedNet
	 * @description 判断是否是连通的网络
	 * @return
	 */
	public boolean isConnectedNet();
	/**
	 * @name insertNode
	 * @description 插入一个节点
	 * @param Map node
	 * @return boolean
	 */	
	public boolean insertNode(Node node);

	/**
	 * @name insertNode
	 * @description 插入一个节点
	 * @param nodeId
	 * @return
	 */
	public boolean insertNode(Number nodeId);
	/**
	 * @name insertEdge
	 * @description 插入一条边
	 * @param Number preNodeId
	 * @param Number postNodeId
	 * @param boolean
	 */
	public boolean insertEdge(final Number preNodeId, final Number postNodeId);
	
	/**
	 * @name insertEdge
	 * @description 插入一条边
	 * @param Number preNodeId
	 * @param Number postNodeId
	 * @param int edgeWeigh
	 * @param boolean
	 */
	public boolean insertEdge(final Number preNodeId, final Number postNodeId, int edgeWeigh);
	
	/**
	 * @name insertEdge
	 * @description 插入一条边
	 * @param Number preNodeId
	 * @param int preNodeWeigh
	 * @param Number postNodeId
	 * @param int postNodeWeigh
	 * @param boolean
	 */
	public boolean insertEdge(final Number preNodeId, int preNodeWeigh, final Number postNodeId, int postNodeWeigh);

	/**
	 * @name insertEdge
	 * @description 插入一条边
	 * @param Number preNodeId
	 * @param int preNodeWeigh
	 * @param Number postNodeId
	 * @param int postNodeWeigh
	 * @param int edgeWeigh
	 * @param boolean
	 */
	public boolean insertEdge(final Number preNodeId, int preNodeWeigh, final Number postNodeId, int postNodeWeigh, int edgeWeigh);


	/**
	 * @name deleteNode
	 * @description 删除一个节点
	 * @param Number nodeId
	 * @return boolean
	 */
	public void deleteNode(Number nodeId);
	
	/**
	 * @name deleteEdge
	 * @description 删除一条边
	 * @param Number preNodeId
	 * @param Number postNodeId
	 * @return 
	 */
	public void deleteEdge(Number preNodeId, Number postNodeId);
	
	/**
	 * @return 
	 * @name DFS
	 * @description 深度优先遍历网络
	 */
	public ArrayList<Number> DFS();
	/**
	 * @return 
	 * @name BFS
	 * @description 广度优先遍历网络
	 */
	public ArrayList<Number>  BFS();
	
	/**
	 * 
	 * @name traverseEdge
	 * @description 遍历网络中的边
	 * @return PairList
	 */
	public PairList<Number, Number> traverseEdge();
	
	/**
	 * @name copyNet
	 * @description 创建网络拓扑副本
	 * @return Network
	 */
	public Network copyNet();
	
	/**
	 * @name saveNetToFile
	 * @description 将网络拓扑保存到文件
	 * @param String fileName
	 * @param String netFileFormat
	 * @return boolean
	 */
	public boolean saveNetTofile(String fileName, Global.NetFileFormat netFileFormat);
}
